package cn.rcth.controller;

import cn.rcth.base.VO.JsonResultVO;
import cn.rcth.base.VO.VerifyCodeVO;
import cn.rcth.base.constants.BaiseConstants;
import cn.rcth.base.domain.User;
import cn.rcth.base.domain.VerifyCode;
import cn.rcth.base.enums.ErrorCode;
import cn.rcth.base.msg.ResultMsg;
import cn.rcth.base.msg.WxOpenMsg;
import cn.rcth.base.serivce.IUserSerivce;
import cn.rcth.base.serivce.impl.SessionOrOpenId;

import cn.rcth.base.util.Assert;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.codehaus.xfire.util.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信登录

     * @Description: 解密用户敏感数据
     * @param encryptedData 明文,加密数据
 * @param iv   加密算法的初始向量
 * @param code  用户允许登录后，回调内容会带上 code（有效期五分钟），开发者需要将 code 发送到开发者服务器后台，使用code 换取 session_key api，将 code 换成 openid 和 session_key
 * @return*/
@Controller
public class LoginController {

    @Autowired
    private SessionOrOpenId sessionOrOpenId;

    @Autowired
    private IUserSerivce userSerivce;

    /**
     * 授权登录
     *
     * @param encryptedData 加密文件
     * @param iv            解密
     * @param code          唯一id
     * @return opneid   sessionkey
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    @RequestMapping(value = "/decodeUserInfo", method = RequestMethod.POST)
    @ResponseBody
    public ResultMsg decodeUserInfo(String encryptedData, String iv, String code) {
        System.out.println(code);
        // 登录凭证不能为空  product
        if (code == null || code.length() == 0) {
            Map map = new HashMap();
            map.put("status", 0);
            map.put("msg", "code 不能为空");
            return ResultMsg.successResult(map);
        }
        WxOpenMsg openMsg = sessionOrOpenId.getSessionOrOpenId(code);
        //判断当前用户是否存在并存储用户默认信息
        User user = userSerivce.ifUser(openMsg);
        openMsg.setUserId(user.getId());
        return ResultMsg.successResult(openMsg);
    }

    /**
     * 保存手机号
     * @param phone 手机号1
     * @return
     */
    @RequestMapping(value = "/savePhone", method = RequestMethod.POST)
    @ResponseBody
    public JsonResultVO savePhone(Long userId ,String phone){

        userSerivce.savePhone(userId,phone);
        return JsonResultVO.success();

    }

    /**
     * 用户授权保存基本信息
     * @param userId 用户id
     * @param gender 性别
     * @param nickName 昵称
     * @param heodImg  头像
     * @return
     */
    @RequestMapping(value = "/saveUser", method = RequestMethod.POST)
    @ResponseBody
    public JsonResultVO saveUser(Long userId , Integer gender, String nickName, String heodImg){
        //保存用户信息
        userSerivce.saveUser(userId,gender,nickName,heodImg);
        return JsonResultVO.success();

    }

    @RequestMapping(value = "/getUser" ,method = RequestMethod.GET)
    @ResponseBody
    public ResultMsg getUser( Long userId){
        User user = userSerivce.getUser(userId);
        return  ResultMsg.successResult(user);

    }

    /**
     * 先验证用户手机验证码后保存用户的信息
     *
     * @param verifyCode 验证码相关信息
     * @return 结果
     */
    @RequestMapping(value = "/decodeUserSave", method = RequestMethod.POST)
    @ResponseBody
    public ResultMsg decodeUserSave(VerifyCode verifyCode, String openId) {
        ResultMsg<Object> objectResultMsg = new ResultMsg<>();
        //判断验证码是否正确
        boolean exists = userSerivce.ifVerifyCode(verifyCode);
        if (exists) {
            //正确保存用户数据并发送注册成功信息
            userSerivce.ifInsertUser(openId,verifyCode.getPhone());
        } else {
            //验证失败  返还错误信息
            objectResultMsg.setMsg(BaiseConstants.COLE_FALSE);
        }
        return ResultMsg.failedResult(BaiseConstants.TRUE_CONTEXT);
    }



    /**
     * 获取信息
     */
    @RequestMapping(value = "/login/userinfo", method = RequestMethod.GET)
    @ResponseBody
    public ResultMsg getUserInfo(String encryptedData, String sessionKey, String iv) {
        // 被加密的数据
        byte[] dataByte = Base64.decode(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decode(sessionKey);
        // 偏移量
        byte[] ivByte = Base64.decode(iv);

        try {
            // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                System.out.println(result);
                HashMap<String, Object> map = new HashMap<>();
                map.put("result",result);
                return ResultMsg.successResult(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
